package com.chap9;

import java.util.Random;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicLong;

/**
 * <p>
 * <code>ConcurrentHashMapDemo</code>
 * </p>
 *
 * @author junbao3
 * TODO
 * @date 2023-03-27 14:46
 * Copyright (C) 2021 IFlyTek. All rights reserved.
 */
public class ConcurrentHashMapDemo {
    private static ConcurrentHashMap<String, AtomicLong> concurrentHashMap = new ConcurrentHashMap<>();

    private static CountDownLatch countDownLatch = new CountDownLatch(3);

    //模拟文本文件中的单词
    private static String[] words = {"we","it","is"};

    public static void main(String[] args) {
        Runnable task = new Runnable() {
            @Override
            public void run() {
                for (int i = 0; i < 3; i++) {
                    //模拟从文本文件中读取到的单词
                    String word = words[new Random().nextInt(3)];
                    //尝试获取全局统计结果
                    AtomicLong number = concurrentHashMap.get(word);
                    //未获取到的情况下，进行初次统计结果设置
                    if (number==null){
                        //在设置时发现如果不存在 则初始化
                        AtomicLong newNumber = new AtomicLong(0);
                        number = concurrentHashMap.putIfAbsent(word,newNumber);
                        if (number == null){
                            //put进去的时候，value不存在 也就是put成功了 number就是初始化的值
                            number = newNumber;
                        }
                        //put进去的时候，value存在 也就是put失败了 number就是真实值 直接到下面去累加
                    }
                    //map有这个单词对应的数量，加1
                    number.incrementAndGet();
                    System.out.println(Thread.currentThread().getName()+":"+word+"出现"+number+"次");
                }
                countDownLatch.countDown();
            }
        };

        new Thread(task,"线程1").start();
        new Thread(task,"线程2").start();
        new Thread(task,"线程3").start();

        try {
            countDownLatch.await();
            System.out.println(concurrentHashMap.toString());
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}
